This page last changed on Sep 08, 2006 by bowens.

LESSON 4: WMS Capabilities and Styling Your Map

Here we will talk about the WMS GetMap service that, when combined with SLD, will give users beautiful maps.

For this page make sure you have an instance of GeoServer running so you can try it out on the fly.

WMS (Web Mapping Service) Request Overview

The WMS protocol is a standard for requesting maps from a GIS server. There are several request types for WMS; the most commonly used is the Get Map request that basically lets you view the map as raster image (gif, png, jpeg etc.). Another type of request is the Get Feature Info request that allows you to query the data of a raster image. We will take a look at the Get Map request.

There are eight main parts to a WMS GetMap request. They are as follows:

  • URL of the server
  • Request type
  • Layers to be rendered
  • Styles to render the layers with
  • What projection you want the layers rendered in
  • Dimentions of the map you want (in pixels)
  • Format of the image (png, jpeg etc.)
  • Bounding box of the view

Here is what the request looks like:

http://example.com:8080/geoserver/wms?
request=GetMap&
layers=topp:states&
styles=population&
srs=EPSG:4326&
width=600&height=600&
format=image/png&
bbox=-126.325,12.797,-63.691,62.905

To Try it out, copy the following URL into your web browser and hit Enter. You should have an image returned. (Make sure GeoServer is running!)
http://localhost:8080/geoserver/wms?request=GetMap&layers=topp:states&styles=population&srs=EPSG:4326&width=600&height=600&format=image/png&bbox=-126.325,12.797,-63.691,62.905

WMS Output formats

The format parameter of the WMS request allows you to specify in what format you want the map returned in. This is server-dependant. GeoServer allows for the following output formats:

Multiple Layers

You can request multiple layers to be returned as one map. All you have to do is list each layer, separated by a comma, in the layers parameter. You also have to supply a style for each layer, separated by commas. For example:

layers=topp:states,topp:countries&
styles=population,polygon

The order that you specify the layers is the order that they will be rendered in.

ASSIGNMENT- Multiple layer request

Create a WMS request that will combine these following layers into a map:
topp:countries
topp:states
topp:tasmania_state_boundaries
topp:tasmania_water_bodies
topp:tasmania_roads
topp:tasmania_cities

You can use default styles or look in the Feature Type editor and see what styles the layers are using.

SLD (Styled Layer Descriptor) Introduction

SLD's are XML files that describe how a map should be rendered. Each FeatureType has a default SLD that it uses to render itself when a WMS GetMap request is called. And SLD document can specify rendering options such as:

  • Line width
  • Line color
  • Line width
  • Line dashes
  • Point color
  • Polygon color
  • Opacity
  • Textures
  • Scale ranges
  • Filters
  • Labels
  • Icons
  • and much more ...

SLD Tutorial

ASSIGNMENT- Create an SLD document

Follow the next few steps to create an SLD document.

Step 1: SLD Wizard

The easiest way to get used to SLDs is to try the built in SLD wizard that comes with GeoServer. To find it, navigate to the Feature Type editor screen and select your countries layer.

Select the Countries feature type and hit the Edit button. Now you are in the feature type editor. Locate the Create new SLD button and click on it. This will take you to the SLD wizard.
Fill out the information on the wizard page by specifying the color and opacity of the shapes (outline and fill). Also select a field that will be used as the label.
When you are done, hit the Submit button. This will send the SLD to the configuration. Finally hit the Finished button to return to the feature type editor page.

Locate the Style drop down list and find the style called countries_style. The SLD wizard created the SLD and named it "<featureTypeName>_style". Select the style and then hit the Submit button at the bottom of the page. Once this is done, hit Apply and then Save.

Step 2: Hand-Made SLD

Open up your favorite text editor and enter the following XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<StyledLayerDescriptor version="1.0.0" 
    xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd" 
    xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" 
    xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<NamedLayer>
<Name>A Test Layer</Name>
<UserStyle>
  <Name>mystyle</Name>
  <Title>Title of the style</Title>
  <Abstract>Just some text</Abstract>
  <FeatureTypeStyle>
  
      <!-- SLD madness goes in here -->

  </FeatureTypeStyle>
</UserStyle>
</NamedLayer>
</StyledLayerDescriptor>

You now have the shell for an SLD. Inside of the <FeatureTypeStyle> tag go rules ( <Rule> ). You can have multiple rules, each one describing how to draw the geometries. So lets start by adding a blank rule. Between the <FeatureTypeStyle> tags, add the following xml:

<Rule>
        <PolygonSymbolizer>
          <Fill/>
        </PolygonSymbolizer>
      </Rule>

The next step will go into detail what a Polygon Symbolizer is.

Save your file anywhere on your hard drive and call it mystyle.sld.
Next lets tell GeoServer about our style. Navigate to the Style editor ( Config -> Data -> Style ). Click on New to create a new style for GeoServer.

Where it asks for a StyleID enter mystyle. (You can call it whatever you want really). Then hit New. You will be taken to the next page where you locate the file you just created. Click on the Browse button next to "Filename" and find your file.
Make sure that "Fully Validate against the SLD schema" is checked.
When done, hit the Submit button. If your SLD is valid, you will return to the config page. If there was an error, it will tell you where the error is (usually just a typo).
Finally, hit Apply and Save to save the conifguration.

You now have a new style!

Next, you should tell the feature type to use the style. Navigate to the feature type editor (config -> data -> feature types) and select your countries layer. Hit the Edit button, this will take you to the editor. In the editor, locate the Style drop down list and find your style. Select the style and then hit the Submit button at the bottom of the page. Once this is done, hit Apply and then Save.
You can preview the change by clicking on this link:
preview
(This link makes a simple WMS request similar to what we talked about above)

Step 3: Simple polygons - Welcome to Symbolizers

Symbolizers are the core of the SLD document: they describe the size and colors of everything to be rendered.
There are four main symbolizers:

  • PointSymbolizer
  • LineSymbolizer
  • PolygonSymbolizer
  • TextSymbolizer

Symbolizers allow you to style your geometries with various values such as: color, opacity, texture, thickness.

We are going to add a PolygonSymbolizer to our SLD document so we can color our polygons. Simply modify your existing file to contain this symbolizer:

<PolygonSymbolizer>
          <Fill>
            <CssParameter name="fill">#FF0000</CssParameter>
            <CssParameter name="fill-opacity">0.7</CssParameter>
          </Fill>
        </PolygonSymbolizer>

This will color the polygons red with an opacity of 70%.

Save the file and update it in geoserver:

Update a Style simple-steps
  1. Navigate to the Style editor: (config -> data -> style)
  2. Select your style from the drop down list
  3. Hit the Edit button
  4. For the 'filename' field, hit the Browse button.
  5. Locate your file and hit OK
  6. Hit the Submit button
  7. Hit Apply and then Save to save out the changes
    Your style is now updated!

Step 4: Polygons with outlines

PolygonSymbolizers can also draw outlines for the polygons. All you have to add is a <stroke> to the symbolizer so it looks like this:

<PolygonSymbolizer>
          <Fill>
            <CssParameter name="fill">#FF0000</CssParameter>
            <CssParameter name="fill-opacity">0.7</CssParameter>
          </Fill>
          <Stroke>
            <CssParameter name="stroke">#00FF00</CssParameter>
            <CssParameter name="stroke-width">2</CssParameter>
          </Stroke>
        </PolygonSymbolizer>

Apply and save the changes again.
Make sure to preview it to see how it turned out.

Step 5: Texture Fill

Sometimes you might want to fill your polygons with a texture. That is easy to do with SLD. There are two things you have to do: modify the SLD document, and select an image to use.

First we will modify our symbolizer to use textures. Replace the <Fill> portion of your polygon symbolizer with the xml below:

<Fill>
            <GraphicFill>
              <Graphic>
                <ExternalGraphic>
                  <OnlineResource xlink:type="simple" xlink:href="grass_fill.png"/>
                  <Format>image/png</Format>
                </ExternalGraphic>
                <Opacity>1.0</Opacity>
                <Size>30</Size>
                <Rotation>0.5</Rotation>
              </Graphic>
            </GraphicFill>
          </Fill>

Next, place grass_fill.png image in the location where your styles are. These are in the data directory of GeoServer, in the sub directory called styles. If you don't know where that is, simply search for your sld document mystyle.sld and put the file in that location.

Step 6: Labels

Labels are the text that appears on your geometries. It might be a street name or a country name. Whatever you want it to be. You use a TextSymbolizer to pull this off. A text symbolizer can display text from any field in your feature and you can also specify how it looks: color, size, font, outline.Labels are the text that appears on your geometries. It might be a street name or a country name. Whatever you want it to be. You use a TextSymbolizer to pull this off. A text symbolizer can display text from any field in your feature and you can also specify how it looks: color, size, font, outline.
To try it out, modify your SLD document to look like this:

<Rule>
        <PolygonSymbolizer>
            <!-- .... leave your polygon symbolizer here .... -->
        </PolygonSymbolizer>
        <TextSymbolizer>
          <Label>
              <ogc:PropertyName>COUNTRY_NA</ogc:PropertyName>
          </Label>
          <Font>
              <CssParameter name="font-family">Times New Roman</CssParameter>
              <CssParameter name="font-style">Normal</CssParameter>
              <CssParameter name="font-size">14</CssParameter>
          </Font>
          <Fill>
              <CssParameter name="fill">#0000FF</CssParameter>
          </Fill>
        </TextSymbolizer>
      </Rule>

This will draw the corresponding text for the COUNTRY_NA value of each feature.

Apply and save your style. Preview it to see that it worked.

Step 7: Scale Denominators

Scale denominators are what make SLD very useful. With them you can specify what scale range to render a specific rule. For instance, you can have several rules each with their own scale denominator what will render the map differently depending how zoomed in you are.
The scale denominator goes before all the symbolizers and they look like this:

<MinScaleDenominator>800000</MinScaleDenominator>
        <MaxScaleDenominator>52000000</MaxScaleDenominator>

You can have max or min alone, or combined.

Here is an example SLD document with several rules:

<Rule>
    <MinScaleDenominator>3000000</MinScaleDenominator>
    <LineSymbolizer>
      <Stroke>
        <CssParameter name="stroke">#FF0000</CssParameter>
        <CssParameter name="stroke-width">4</CssParameter>
      </Stroke>
    </LineSymbolizer>
</Rule>
<Rule>
    <MinScaleDenominator>1000000</MinScaleDenominator>
    <MaxScaleDenominator>3000000</MaxScaleDenominator>
    <LineSymbolizer>
      <Stroke>
        <CssParameter name="stroke">#00FF00</CssParameter>
        <CssParameter name="stroke-width">2</CssParameter>
      </Stroke>
    </LineSymbolizer>
</Rule>
<Rule>
    <MaxScaleDenominator>1000000</MaxScaleDenominator>
    <LineSymbolizer>
      <Stroke>
        <CssParameter name="stroke">#0000FF</CssParameter>
        <CssParameter name="stroke-width">1</CssParameter>
      </Stroke>
    </LineSymbolizer>
</Rule>

This will render:

  • thick red roads in the scale range 3,000,000 and above
  • green roads in the scale range 1,000,000 to 3,000,000
  • thin blue roads in the scale range lower than 1,000,000

So as the user zooms in, the roads will go from red, to green, to blue.

Try adding scale denominators to your SLD document.

Step 8: Basic Filters

Filters are another great tool that SLD provides. With filters you can have your rules render only features that pass certain criteria. For instance, you can color the countries based on their population.
Here is an example:

<Rule>
        <ogc:Filter xmlns:gml="http://www.opengis.net/gml">
          <ogc:PropertyIsBetween>
            <ogc:PropertyName>APPROX_POP</ogc:PropertyName>
            <ogc:LowerBoundary>
              <ogc:Literal>100000000</ogc:Literal>
            </ogc:LowerBoundary>
            <ogc:UpperBoundary>
              <ogc:Literal>900000000</ogc:Literal>
            </ogc:UpperBoundary>
          </ogc:PropertyIsBetween>
        </ogc:Filter>

        <MaxScaleDenominator>1000000</MaxScaleDenominator>
        <PolygonSymbolizer>
          <Fill>
            <CssParameter name="fill">#FF0000</CssParameter>
            <CssParameter name="fill-opacity">0.7</CssParameter>
          </Fill>
        </PolygonSymbolizer>
      </Rule>

This example uses the Property Is Between filter to test if a feature's property value is between a specified range. It will render all countries that have a population greater than 100 million and lower than 900 million in a red fill at 70% opacity.

Note: Filters come before scale denominators, and scale denominators come before symbolizers.

There are other filters you can use. Here are some examples taken from real SLD documents:

<ogc:Filter>
	<ogc:PropertyIsGreaterThan>
		<ogc:PropertyName>population</ogc:PropertyName>
		<ogc:Literal>1000000</ogc:Literal>
	</ogc:PropertyIsGreaterThan>
</ogc:Filter>

-------------------

<ogc:Filter>
	<ogc:Not>
		<ogc:PropertyIsNull>
			<ogc:PropertyName>GEOMETRY</ogc:PropertyName>
		</ogc:PropertyIsNull>
	</ogc:Not>
</ogc:Filter>

-------------------

<ogc:Filter>
	<ogc:And>
	<ogc:And>
	<ogc:And>
	<ogc:And>
	<ogc:And>
		<ogc:Not>
			<ogc:PropertyIsEqualTo>
				<ogc:PropertyName>type</ogc:PropertyName>
				<ogc:Literal>Populated Place</ogc:Literal>
			</ogc:PropertyIsEqualTo>
		</ogc:Not>
		<ogc:Not>
			<ogc:PropertyIsEqualTo>
				<ogc:PropertyName>type</ogc:PropertyName>
				<ogc:Literal>City/Town</ogc:Literal>
			</ogc:PropertyIsEqualTo>
		</ogc:Not>
	</ogc:And>
		<ogc:Not>
			<ogc:PropertyIsEqualTo>
				<ogc:PropertyName>type</ogc:PropertyName>
				<ogc:Literal>Seat Of A First-order Administrative Division</ogc:Literal>
			</ogc:PropertyIsEqualTo>
		</ogc:Not>
	</ogc:And>
		<ogc:Not>
			<ogc:PropertyIsEqualTo>
				<ogc:PropertyName>type</ogc:PropertyName>
				<ogc:Literal>Seat Of A Second-order Administrative Division</ogc:Literal>
			</ogc:PropertyIsEqualTo>
		</ogc:Not>
	</ogc:And>
		<ogc:Not>
			<ogc:PropertyIsEqualTo>
				<ogc:PropertyName>type</ogc:PropertyName>
				<ogc:Literal>Seat Of A Second-order Administrative Division</ogc:Literal>
			</ogc:PropertyIsEqualTo>
		</ogc:Not>
	</ogc:And>
		<ogc:Not>
			<ogc:PropertyIsEqualTo>
				<ogc:PropertyName>type</ogc:PropertyName>
				<ogc:Literal>Capital Of A Political Entity</ogc:Literal>
			</ogc:PropertyIsEqualTo>
		</ogc:Not>
	</ogc:And>
</ogc:Filter>

-------------------

<ogc:Filter> 
    <ogc:Or>
	 <ogc:And>
	   <ogc:PropertyIsEqualTo>
		<ogc:PropertyName>cfcc_1</ogc:PropertyName>
		<ogc:Literal>D</ogc:Literal>
	   </ogc:PropertyIsEqualTo>
	   <ogc:PropertyIsEqualTo>
		<ogc:PropertyName>cfcc_2</ogc:PropertyName>
		<ogc:Literal>8</ogc:Literal>
	   </ogc:PropertyIsEqualTo>
	 </ogc:And>
	 <ogc:Or>
	     <ogc:PropertyIsEqualTo>
		<ogc:PropertyName>cfcc</ogc:PropertyName>
		<ogc:Literal>D10</ogc:Literal>
	     </ogc:PropertyIsEqualTo>
	     <ogc:PropertyIsEqualTo>
		<ogc:PropertyName>cfcc</ogc:PropertyName>
		<ogc:Literal>D28</ogc:Literal>
	     </ogc:PropertyIsEqualTo>
	</ogc:Or>
    </ogc:Or>
</ogc:Filter>

Try Your Own

If you have some extra time, try making your own SLD combining all of the features you have just learned.
Create a style for Countries layer that will color each country based on its population (APPROX_POP). Set about three or four different population ranges. After that, make the SLD only render those population colors when you are zoomed in a little ways. But make sure that at least a basic outline is always drawn for the countries no matter what scale range you are in.


Document generated by Confluence on Jan 16, 2008 23:27